package com.w4cms.kits;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.lang.StringUtils;

/**
 * https 请求 微信为https的请求
 * 
 * @author L.cm
 * @date 2013-10-9 下午2:40:19
 */
public class HttpKit {

	private static final String DEFAULT_CHARSET = "UTF-8";
	private static final String UA = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";

	/**
	 * 
	 * @description 功能描述: get 请求
	 * @author 作 者: 卢春梦
	 * @param 参
	 *            数:
	 * @return 返回类型:
	 * @createdate 建立日期：2013-10-22上午9:44:48
	 */
	public static String get(String url) {
		StringBuffer bufferRes = null;
		try {
			URL urlGet = new URL(url);
			HttpURLConnection http = (HttpURLConnection) urlGet
					.openConnection();
			// 连接超时
			http.setConnectTimeout(25000);
			// 读取超时 --服务器响应比较慢，增大时间
			http.setReadTimeout(25000);
			http.setRequestMethod("GET");
			http.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			http.setRequestProperty("User-Agent", UA);
			http.setDoOutput(true);
			http.setDoInput(true);
			http.connect();

			InputStream in = http.getInputStream();
			BufferedReader read = new BufferedReader(new InputStreamReader(in,
					DEFAULT_CHARSET));
			String valueString = null;
			bufferRes = new StringBuffer();
			while ((valueString = read.readLine()) != null) {
				bufferRes.append(valueString);
			}
			in.close();
			if (http != null) {
				// 关闭连接
				http.disconnect();
			}
			return bufferRes.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 
	 * @description 功能描述: get 请求
	 * @author 作 者: 卢春梦
	 * @param 参
	 *            数:
	 * @return 返回类型:
	 * @createdate 建立日期：2013-10-22上午9:44:22
	 */
	public static String get(String url, Map<String, String> params) {
		return get(initParams(url, params));
	}

	/**
	 * 
	 * @description 功能描述: get 请求 https
	 * @author 作 者: 卢春梦
	 * @param 参
	 *            数:
	 * @return 返回类型:
	 * @createdate 建立日期：2013-10-21下午6:41:48
	 */
	public static String getWithSSL(String url) {
		StringBuffer bufferRes = null;
		try {
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL urlGet = new URL(url);
			HttpsURLConnection http = (HttpsURLConnection) urlGet
					.openConnection();
			// 设置域名校验
			http.setHostnameVerifier(new HttpKit().new TrustAnyHostnameVerifier());
			// 连接超时
			http.setConnectTimeout(25000);
			// 读取超时 --服务器响应比较慢，增大时间
			http.setReadTimeout(25000);
			http.setRequestMethod("GET");
			http.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			http.setSSLSocketFactory(ssf);
			http.setDoOutput(true);
			http.setDoInput(true);
			http.connect();

			InputStream in = http.getInputStream();
			BufferedReader read = new BufferedReader(new InputStreamReader(in,
					DEFAULT_CHARSET));
			String valueString = null;
			bufferRes = new StringBuffer();
			while ((valueString = read.readLine()) != null) {
				bufferRes.append(valueString);
			}
			in.close();
			if (http != null) {
				// 关闭连接
				http.disconnect();
			}
			return bufferRes.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 
	 * @description 功能描述: get请求https
	 * @author 作 者: 卢春梦
	 * @param 参
	 *            数:
	 * @return 返回类型:
	 * @createdate 建立日期：2013-10-21下午6:41:42
	 */
	public static String getWithSSL(String url, Map<String, String> params) {
		return getWithSSL(initParams(url, params));
	}

	/**
	 * 
	 * @description 功能描述: POST 请求
	 * @author 作 者: 卢春梦
	 * @param 参
	 *            数:
	 * @return 返回类型:
	 * @createdate 建立日期：2013-10-21下午6:42:07
	 */
	public static String post(String url, String params) {
		StringBuffer bufferRes = null;
		try {
			URL urlGet = new URL(url);
			HttpURLConnection http = (HttpURLConnection) urlGet
					.openConnection();
			// 连接超时
			http.setConnectTimeout(25000);
			// 读取超时 --服务器响应比较慢，增大时间
			http.setReadTimeout(25000);
			http.setRequestMethod("POST");
			http.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			http.setRequestProperty("User-Agent", UA);
			http.setDoOutput(true);
			http.setDoInput(true);
			http.connect();

			OutputStream out = http.getOutputStream();
			out.write(params.getBytes("UTF-8"));
			out.flush();
			out.close();

			InputStream in = http.getInputStream();
			BufferedReader read = new BufferedReader(new InputStreamReader(in,
					DEFAULT_CHARSET));
			String valueString = null;
			bufferRes = new StringBuffer();
			while ((valueString = read.readLine()) != null) {
				bufferRes.append(valueString);
			}
			in.close();
			if (http != null) {
				// 关闭连接
				http.disconnect();
			}
			return bufferRes.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 
	 * @description 功能描述: POST 请求
	 * @author 作 者: 卢春梦
	 * @param 参
	 *            数:
	 * @return 返回类型:
	 * @createdate 建立日期：2013-10-21下午6:42:07
	 */
	public static String postWithSSL(String url, String params) {
		StringBuffer bufferRes = null;
		try {
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL urlGet = new URL(url);
			HttpsURLConnection http = (HttpsURLConnection) urlGet
					.openConnection();
			// 设置域名校验
			http.setHostnameVerifier(new HttpKit().new TrustAnyHostnameVerifier());
			// 连接超时
			http.setConnectTimeout(25000);
			// 读取超时 --服务器响应比较慢，增大时间
			http.setReadTimeout(25000);
			http.setRequestMethod("POST");
			http.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			http.setSSLSocketFactory(ssf);
			http.setDoOutput(true);
			http.setDoInput(true);
			http.connect();

			OutputStream out = http.getOutputStream();
			out.write(params.getBytes("UTF-8"));
			out.flush();
			out.close();

			InputStream in = http.getInputStream();
			BufferedReader read = new BufferedReader(new InputStreamReader(in,
					DEFAULT_CHARSET));
			String valueString = null;
			bufferRes = new StringBuffer();
			while ((valueString = read.readLine()) != null) {
				bufferRes.append(valueString);
			}
			in.close();
			if (http != null) {
				// 关闭连接
				http.disconnect();
			}
			return bufferRes.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	// https 域名校验
	public class TrustAnyHostnameVerifier implements HostnameVerifier {
		public boolean verify(String hostname, SSLSession session) {
			return true;// 直接返回true
		}
	}

	/**
	 * post map
	 * 
	 * @param url
	 * @param params
	 * @return
	 */
	public static String post(String url, Map<String, String> params) {
		return post(url, map2Url(params));
	}

	/**
	 * 
	 * @description 功能描述: 构造请求参数
	 * @author 作 者: 卢春梦
	 * @param 参
	 *            数:
	 * @return 返回类型:
	 * @createdate 建立日期：2013-10-21下午6:40:35
	 */
	public static String initParams(String url, Map<String, String> params) {
		if (null == params || params.isEmpty()) {
			return url;
		}
		StringBuilder sb = new StringBuilder(url);
		if (url.indexOf("?") == -1) {
			sb.append("?");
		} else {
			sb.append("&");
		}
		boolean first = true;
		for (Entry<String, String> entry : params.entrySet()) {
			if (first) {
				first = false;
			} else {
				sb.append("&");
			}
			String key = entry.getKey();
			String value = entry.getValue();
			sb.append(key).append("=");
			if (StringUtils.isNotEmpty(value)) {
				try {
					sb.append(URLEncoder.encode(value, DEFAULT_CHARSET));
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			}
		}
		return sb.toString();
	}

	/**
	 * map构造url
	 * 
	 * @description 功能描述:
	 * @author 作 者: 卢春梦
	 * @param 参
	 *            数:
	 * @return 返回类型:
	 * @createdate 建立日期：2013-11-19下午4:58:39
	 */
	public static String map2Url(Map<?, ?> paramToMap) {
		if (null == paramToMap || paramToMap.isEmpty()) {
			return null;
		}
		StringBuffer url = new StringBuffer();
		boolean isfist = true;
		for (Entry<?, ?> entry : paramToMap.entrySet()) {
			if (isfist) {
				isfist = false;
			} else {
				url.append("&");
			}
			url.append(entry.getKey()).append("=").append(entry.getValue());
		}
		return url.toString();
	}
}

// 证书管理
class MyX509TrustManager implements X509TrustManager {

	public X509Certificate[] getAcceptedIssuers() {
		return null;
	}

	public void checkClientTrusted(X509Certificate[] chain, String authType)
			throws CertificateException {
	}

	public void checkServerTrusted(X509Certificate[] chain, String authType)
			throws CertificateException {
	}
}